package com.own.business.system.dictionary.business.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.own.business.system.dictionary.business.service.SystemDictionaryItemService;
import com.own.business.system.dictionary.business.service.SystemDictionaryService;
import com.own.business.system.dictionary.common.em.DictionaryExceptionEnum;
import com.own.business.system.dictionary.common.exception.DictionaryException;
import com.own.business.system.dictionary.entity.bo.SystemDictionaryItemBo;
import com.own.business.system.dictionary.entity.map.SystemDictionaryItemMapVo;
import com.own.business.system.dictionary.entity.po.SystemDictionaryItem;
import com.own.business.system.dictionary.entity.query.SystemDictionaryItemQuery;
import com.own.business.system.dictionary.entity.vo.SystemDictionaryItemVo;
import com.own.business.system.dictionary.mapper.SystemDictionaryItemMapper;
import com.own.component.common.base.service.impl.AbstractBaseService;
import com.own.component.common.model.UpdateModel;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * SystemDictionaryItemServiceImpl
 *
 * @author chenxueli
 * @date 2023-06-21 09:54:24
 */
@Slf4j
@Service
public class SystemDictionaryItemServiceImpl extends AbstractBaseService<
        SystemDictionaryItem,
        SystemDictionaryItemBo,
        SystemDictionaryItemVo,
        SystemDictionaryItemMapVo,
        SystemDictionaryItemQuery,
        SystemDictionaryItemMapper
        > implements SystemDictionaryItemService {

    @Resource
    private SystemDictionaryItemMapper systemDictionaryItemMapper;

    @Resource
    private SystemDictionaryService systemDictionaryService;

    @Override
    public LambdaQueryWrapper<SystemDictionaryItem> lambdaQueryWrapper(SystemDictionaryItemQuery query) {
        return super.lambdaQueryWrapper(query)
                .like(StringUtils.isNotEmpty(query.getName()), SystemDictionaryItem::getName, query.getName())
                .like(StringUtils.isNotEmpty(query.getValue()), SystemDictionaryItem::getValue, query.getValue())
                .eq(query.getDictionaryId() != null, SystemDictionaryItem::getFkDictionaryId, query.getDictionaryId())
                .eq(query.getIsDisable() != null, SystemDictionaryItem::getIsDisable, query.getIsDisable())
                .eq(query.getIsEdit() != null, SystemDictionaryItem::getIsEdit, query.getIsEdit())
                .orderByAsc(SystemDictionaryItem::getSortOrder)
                .orderByDesc(SystemDictionaryItem::getGmtCreate);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public UpdateModel<SystemDictionaryItemVo> add(SystemDictionaryItem systemDictionaryItem) {
        // 判断上级是否存在
        systemDictionaryService.getById(systemDictionaryItem.getFkDictionaryId());
        // 判断是否存在同名的
        var wrapper = lambdaQueryWrapper().eq(SystemDictionaryItem::getName, systemDictionaryItem.getName());
        if (systemDictionaryItemMapper.selectCount(wrapper) > 0) {
            throw new DictionaryException(DictionaryExceptionEnum.NAME_DUPLICATE);
        }
        if (systemDictionaryItem.getSortOrder() == null) {
            var maxOrder = systemDictionaryItemMapper.maxSortOrder(lambdaQueryWrapper().eq(SystemDictionaryItem::getFkDictionaryId, systemDictionaryItem.getFkDictionaryId()));
            systemDictionaryItem.setSortOrder(maxOrder + 1);
        }
        return super.add(systemDictionaryItem);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public UpdateModel<SystemDictionaryItemVo> update(SystemDictionaryItem systemDictionaryItem) {
        // 判断是否存在同名的
        var wrapper = lambdaQueryWrapper()
                .eq(SystemDictionaryItem::getName, systemDictionaryItem.getName())
                .ne(SystemDictionaryItem::getId, systemDictionaryItem.getId());
        if (systemDictionaryItemMapper.selectCount(wrapper) > 0) {
            throw new DictionaryException(DictionaryExceptionEnum.NAME_DUPLICATE);
        }
        if (systemDictionaryItem.getSortOrder() == null) {
            var maxOrder = systemDictionaryItemMapper.maxSortOrder(lambdaQueryWrapper().eq(SystemDictionaryItem::getFkDictionaryId, systemDictionaryItem.getFkDictionaryId()));
            systemDictionaryItem.setSortOrder(maxOrder + 1);
        }
        return super.update(systemDictionaryItem);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public UpdateModel<SystemDictionaryItemVo> update(Long pk, SystemDictionaryItemBo bo) {
        var po = getPoById(pk);
        if (po.getIsEdit() == 0) {
            throw new DictionaryException(DictionaryExceptionEnum.UNABLE_EDIT);
        }
        return super.update(pk, bo);
    }

    @Override
    public List<SystemDictionaryItemMapVo> map(SystemDictionaryItemQuery query) {
        query.setIsDisable(0);
        return super.map(query);
    }

    /**
     * 根据数据字典类型的code查询
     *
     * @param code code值
     * @return 返回列表
     */
    @Override
    public List<SystemDictionaryItemMapVo> mapByDictionaryCode(String code) {
        var dictionary = systemDictionaryService.getByCode(code);
        if (dictionary == null) {
            return new ArrayList<>();
        }
        var query = new SystemDictionaryItemQuery().setDictionaryId(dictionary.getId());
        return map(query).stream().peek(item -> item.setDictionaryId(null)).collect(Collectors.toList());
    }

    /**
     * 根据name和rootCode获取id
     *
     * @param name     名称
     * @param rootCode 根code
     * @return id
     */
    @Override
    public Long getIdByNameAndRootCode(String name, String rootCode) {
        var dictionary = systemDictionaryService.getByCode(rootCode);
        if (dictionary == null) {
            return null;
        }
        var wrapper = lambdaQueryWrapper()
                .eq(SystemDictionaryItem::getName, name)
                .eq(SystemDictionaryItem::getIsDisable, 0)
                .eq(SystemDictionaryItem::getFkDictionaryId, dictionary.getId());
        var item = systemDictionaryItemMapper.selectOne(wrapper);
        return item == null ? null : item.getId();
    }

    /**
     * 根据code获取字典信息
     *
     * @param code code
     * @return 字典信息
     */
    @Override
    public SystemDictionaryItemMapVo getItemByCode(String code) {
        return null;
    }

}
